﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using RuoVea.OmiApi.UserRoleMenu.Service;
using System.Security.Claims;

namespace RuoVea.Omi.Web.Template.Web.Filters;

public class GlobalAuthorizeFilter : IAuthorizationFilter
{
    private readonly SysMenuService _sysMenuService;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sysMenuService"></param>
    public GlobalAuthorizeFilter(SysMenuService sysMenuService)
    {
        _sysMenuService = sysMenuService;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        if (actionDescriptor != null)
        {
            // 检查控制器或动作上是否有 AllowAnonymous 属性
            var isAllowAnonymous = actionDescriptor.MethodInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute), inherit: false).Any() || actionDescriptor.ControllerTypeInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute), inherit: false).Any();
            if (isAllowAnonymous)
                return;
        }

        var requestPath = context.HttpContext.Request.Path;
        List<PathString> allowAnonymous = new() { "/auth", "/user" };
        if (allowAnonymous.Any(path => requestPath.StartsWithSegments(path, StringComparison.OrdinalIgnoreCase)))
            return;

        ClaimsPrincipal user = context.HttpContext?.User ?? new();
        if (!user?.Identity?.IsAuthenticated ?? false)
        {
            context.Result = new RedirectResult("/auth/login");
            return;
        }

        #region 方式一、
        if (!user!.IsInRole("SuperAdmin"))
        {
            var data = _sysMenuService.GetLoginMenuTree().Result;
            List<string> paths = new();
            // 处理菜单路径，确保路径以/开头
            data.ForEach(x =>
            {
                paths.AddRange(x.Children.Select(y =>
                {
                    // 确保路径以/开头
                    string path = y.Path.Replace("/index", "");
                    return path.StartsWith("/") ? path : $"/{path}";
                }).ToList());
            });

            string requestPathValue = requestPath.Value;
            if (!requestPathValue.StartsWith("/"))
                requestPathValue = $"/{requestPathValue}";
            string firstSegment = ExtractFirstPathSegment(requestPathValue);

            // 检查第一个路径段是否在允许的路径列表中
            // 这里检查路径列表中的每个路径是否以第一个路径段开头
            if (paths.Any(path => requestPath.StartsWithSegments(firstSegment, StringComparison.OrdinalIgnoreCase))) return;
            else
            {
                context.HttpContext!.Response.StatusCode = 403;
                context.Result = new RedirectToActionResult("index", "unauthorized", new { });
                return;
            }
        }
        #endregion

        #region 方式二、
        //bool isAdmin = user?.Claims.Any(c => c.Type == ClaimConst.CLAINM_ISADMIN && c.Value == "true") ?? false;
        //if (isAdmin) return;
        //List<PathString> adminPaths = new() { "/logdiff", "/logex", "/logop", "/logvis", };
        //if (adminPaths.Any(path => requestPath.StartsWithSegments(path, StringComparison.OrdinalIgnoreCase)))
        //{
        //    if (!user!.IsInRole("Admin"))
        //    {
        //        context.HttpContext!.Response.StatusCode = 403;
        //        context.Result = new RedirectToActionResult("index", "home", new { });
        //        return;
        //    }
        //}

        //List<PathString> superAdminPaths = new() { "/user", "/config", "/dicttyp", "/role", "/menu", };
        //if (superAdminPaths.Union(adminPaths).Any(path => requestPath.StartsWithSegments(path, StringComparison.OrdinalIgnoreCase)))
        //{
        //    if (!user!.IsInRole("SuperAdmin"))
        //    {
        //        context.HttpContext!.Response.StatusCode = 403;
        //        context.Result = new RedirectToActionResult("index", "home", new { });
        //        return;
        //    }
        //} 
        #endregion
    }

    /// <summary>
    /// 提取路径的第一个路径段
    /// </summary>
    /// <param name="path">完整路径</param>
    /// <returns>第一个路径段，例如：/Position/pos/109282922 -> /Position</returns>
    private string ExtractFirstPathSegment(string path)
    {
        if (string.IsNullOrEmpty(path) || path == "/")
            return path;

        // 分割路径，获取第一个路径段
        string[] segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
        if (segments.Length > 0)
        {
            return $"/{segments[0]}";
        }

        return path;
    }
}
